import { director, EditBox, game, Mat4, screen, sys, UITransform, Vec3, view } from "cc";
import Core from "../Core";
import UIManager from "../manager/ui/UIManager";

game.on("some_editbox_focus", ()=>{
    Core.inst.manager.ui.autoFitCanvasSize = false;
    Core.inst.manager.ui.canvas.alignCanvasWithScreen = false;
});

game.on("all_editbox_blur", ()=>{
    Core.inst.manager.ui.autoFitCanvasSize = UIManager.setting.autoFit;
    Core.inst.manager.ui.canvas.alignCanvasWithScreen = true;
});

const focusedEditBox: Set<EditBox> = new Set();
let currentEditBox: EditBox = null;

// 用于此函数计算的局部临时变量
const tempMat4 = new Mat4();
const tempVec3_1 = new Vec3();
const tempVec3_2 = new Vec3();
const tempVec3_3 = new Vec3();
const tempVec3_4 = new Vec3();
const cameraWorldPos = new Vec3();

const _matrix = new Mat4();
const _matrix_temp = new Mat4();
const _vec3 = new Vec3();

function EditBoxImp_updateMatrix() {
    if (!this._edTxt) {
        return;
    }

    const node = this._delegate!.node;
    let scaleX = view.getScaleX();
    let scaleY = view.getScaleY();
    const viewport = view.getViewportRect();
    // TODO: implement editBox in PAL
    const dpr = screen.devicePixelRatio;

    node.getWorldMatrix(_matrix);
    const transform = node._getUITransformComp();
    if (!transform) return;
    Vec3.set(_vec3, -transform.anchorX * transform.width, -transform.anchorY * transform.height, _vec3.z);
    Mat4.transform(_matrix, _matrix, _vec3);

    const camera = director.root!.batcher2D.getFirstRenderCamera(node);
    if (!camera) return;

    // 获取camera的世界矩阵
    camera.node.getWorldRT(_matrix_temp);
    // Vec3.set(_vec3, scaleX, scaleY, 1);
    // Mat4.scale(_matrix_temp, _matrix_temp, _vec3);

    // 得到node的世界矩阵
    Mat4.multiply(_matrix_temp, _matrix_temp.invert(), _matrix);

    // 计算画布的变换矩阵
    _matrix.identity();
    Vec3.set(_vec3, scaleX/dpr, scaleY/dpr, 1);
    Mat4.scale(_matrix, _matrix, _vec3);

    const container = game.container;
    let offsetX = parseInt((container && container.style.paddingLeft) || '0');
    offsetX += viewport.x / dpr;
    let offsetY = parseInt((container && container.style.paddingBottom) || '0');
    offsetY += viewport.y / dpr;
    const center = (<any>cc).visibleRect.center;
    Vec3.set(_vec3, center.x + offsetX, center.y + offsetY, 0);
    Mat4.transform(_matrix, _matrix, _vec3);

    Mat4.multiply(_matrix_temp, _matrix, _matrix_temp);

    const a = _matrix_temp.m00;
    const b = _matrix_temp.m01;
    const c = _matrix_temp.m04;
    const d = _matrix_temp.m05;
    const tx = _matrix_temp.m12;
    const ty = _matrix_temp.m13;

    const matrix = `matrix(${a},${-b},${-c},${d},${tx},${-ty})`;
    this._edTxt.style.transform = matrix;
    this._edTxt.style['-webkit-transform'] = matrix;
    this._edTxt.style['transform-origin'] = '0px 100% 0px';
    this._edTxt.style['-webkit-transform-origin'] = '0px 100% 0px';
}

function onEditBoxEditingWindowResize() {
    if (!currentEditBox) return;

    const node = currentEditBox.node;
    const camera = director.root!.batcher2D.getFirstRenderCamera(node);
    if (!camera) {
        console.warn("onEditBoxEditingWindowResize: 未找到节点的渲染相机。");
        return;
    }

    camera.orthoHeight = screen.windowSize.height / view.getScaleY() / 2;
    adjustCamera.call(this);

    const proto = (<any>currentEditBox._impl).constructor.prototype;
    proto._updateMatrix = EditBoxImp_updateMatrix;

    (<any>currentEditBox._impl)._updateMatrix();
}

const editbox_proto = EditBox.prototype as any;
const origin_editBoxEditingDidBegan = editbox_proto._editBoxEditingDidBegan;
const origin_editBoxEditingDidEnded = editbox_proto._editBoxEditingDidEnded;
editbox_proto._editBoxEditingDidBegan = function (... args: any[]) {
    origin_editBoxEditingDidBegan.call(this, ...args);
    if (!sys.isBrowser) return;
    if (sys.os != sys.OS.ANDROID && sys.os != sys.OS.OHOS) return;
    currentEditBox = this as EditBox;
    if (focusedEditBox.size <= 0) {
        game.emit("some_editbox_focus");
        window.addEventListener("resize", onEditBoxEditingWindowResize);
    }
    focusedEditBox.add(this);
};
editbox_proto._editBoxEditingDidEnded = function (...args: any[]) {
    origin_editBoxEditingDidEnded.call(this, ...args);
    if (!sys.isBrowser) return;
    if (sys.os != sys.OS.ANDROID && sys.os != sys.OS.OHOS) return;
    if (focusedEditBox.has(this)) {
        focusedEditBox.delete(this);
        if (focusedEditBox.size <= 0) {
            game.emit("all_editbox_blur");
            window.removeEventListener("resize", onEditBoxEditingWindowResize);
        }
    }
    if (currentEditBox == this) {
        if (focusedEditBox.size > 0) {
            currentEditBox = focusedEditBox.values().next().value;
        } else {
            currentEditBox = null;
        }
    }
};


function adjustCamera() {
    const node = currentEditBox.node;
    const transform = node.getComponent(UITransform);
    if (!transform) return;

    const camera = director.root!.batcher2D.getFirstRenderCamera(node);
    if (!camera) {
        console.warn("onEditBoxEditingWindowResize: 未找到节点的渲染相机。");
        return;
    }

    const w = transform.width;
    const h = transform.height;
    const ax = transform.anchorX;
    const ay = transform.anchorY;

    // EditBox 相对于其锚点的局部坐标顶点
    Vec3.set(tempVec3_1, -ax * w, -ay * h, 0);         // 左下角
    Vec3.set(tempVec3_2, (1 - ax) * w, -ay * h, 0);    // 右下角
    Vec3.set(tempVec3_3, -ax * w, (1 - ay) * h, 0);    // 左上角
    Vec3.set(tempVec3_4, (1 - ax) * w, (1 - ay) * h, 0); // 右上角

    node.getWorldMatrix(tempMat4); // 获取节点的实际世界矩阵

    // 将局部顶点转换到世界坐标
    Vec3.transformMat4(tempVec3_1, tempVec3_1, tempMat4);
    Vec3.transformMat4(tempVec3_2, tempVec3_2, tempMat4);
    Vec3.transformMat4(tempVec3_3, tempVec3_3, tempMat4);
    Vec3.transformMat4(tempVec3_4, tempVec3_4, tempMat4);

    // 计算 EditBox 在世界坐标中的Y轴边界
    const editBoxWorldMinY = Math.min(tempVec3_1.y, tempVec3_2.y, tempVec3_3.y, tempVec3_4.y);
    const editBoxWorldMaxY = Math.max(tempVec3_1.y, tempVec3_2.y, tempVec3_3.y, tempVec3_4.y);

    // 相机属性
    const cameraOrthoHeight = camera.orthoHeight;
    camera.node.getWorldPosition(cameraWorldPos);
    const currentCameraWorldY = cameraWorldPos.y;

    // 相机当前在世界坐标中的Y轴可视范围
    const cameraViewWorldMinY = currentCameraWorldY - cameraOrthoHeight / 2;
    const cameraViewWorldMaxY = currentCameraWorldY + cameraOrthoHeight / 2;

    let targetCameraWorldY = currentCameraWorldY;
    const editBoxWorldHeight = editBoxWorldMaxY - editBoxWorldMinY;

    if (editBoxWorldHeight > cameraOrthoHeight) {
        // EditBox 比相机可视区域高，将相机垂直居中对齐 EditBox
        targetCameraWorldY = (editBoxWorldMinY + editBoxWorldMaxY) / 2;
    } else {
        // EditBox 可以完整容纳在相机可视区域内或更小
        if (editBoxWorldMaxY > cameraViewWorldMaxY) {
            // EditBox 顶部超出相机视野顶部，向上移动相机，使相机视野顶部与 EditBox 顶部对齐
            targetCameraWorldY = editBoxWorldMaxY - cameraOrthoHeight / 2;
        } else if (editBoxWorldMinY < cameraViewWorldMinY) {
            // EditBox 底部超出相机视野底部，向下移动相机，使相机视野底部与 EditBox 底部对齐
            targetCameraWorldY = editBoxWorldMinY + cameraOrthoHeight / 2;
        }
        // 如果 EditBox 已完全在视野内，targetCameraWorldY 将保持 currentCameraWorldY，不进行调整
    }

    // 如果计算出的目标Y坐标与当前不同，则应用调整
    if (Math.abs(targetCameraWorldY - currentCameraWorldY) > 1e-6) { // 使用极小值进行浮点数比较
        camera.node.getWorldPosition(cameraWorldPos); // 获取相机当前完整的世界坐标 (x, y, z)
        // 设置新的世界坐标，保持x和z不变，改变y
        camera.node.setWorldPosition(cameraWorldPos.x, targetCameraWorldY, cameraWorldPos.z);
        // console.log(`相机Y轴已调整: ${currentCameraWorldY.toFixed(2)} -> ${targetCameraWorldY.toFixed(2)}`);
    }

}